package com.eastfair.pay.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.annotation.annotation.cache.Cache;
import com.eastfair.annotation.annotation.cache.Magic;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.certificate.api.CertificateApiFeign;
import com.eastfair.certificate.dto.CertificateOrderDTO;
import com.eastfair.common.dto.JYMainnoResultDTO;
import com.eastfair.common.dto.JYTransactionOrderDTO;
import com.eastfair.common.dto.OrderPaymentPlan;
import com.eastfair.common.req.JYReq;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.database.mybatis.conditions.Wraps;
import com.eastfair.database.mybatis.conditions.query.QueryWrap;
import com.eastfair.pay.api.FinanceFeign;
import com.eastfair.pay.dao.TransactionOrderMapper;
import com.eastfair.pay.dto.ChinaumsLogDTO;
import com.eastfair.pay.dto.JYPaymentDTO;
import com.eastfair.pay.dto.PaymentDTO;
import com.eastfair.pay.dto.TransactionOrderDTO;
import com.eastfair.pay.dto.TransactionOrderPageQuery;
import com.eastfair.pay.entity.CollectRecord;
import com.eastfair.pay.entity.CollectionAccount;
import com.eastfair.pay.entity.JyLog;
import com.eastfair.pay.entity.TransactionOrder;
import com.eastfair.pay.enumeration.TransactionOrderOrderStatusEnum;
import com.eastfair.pay.enumeration.TransactionOrderOrderTypeEnum;
import com.eastfair.pay.enums.OrderStateEnum;
import com.eastfair.pay.exceptioncode.PayExceptionCode;
import com.eastfair.pay.service.ChinaumsLogService;
import com.eastfair.pay.service.CollectRecordService;
import com.eastfair.pay.service.CollectionAccountService;
import com.eastfair.pay.service.JyLogService;
import com.eastfair.pay.service.JyService;
import com.eastfair.pay.service.PaymentPlanService;
import com.eastfair.pay.service.TransactionOrderService;
import com.eastfair.pay.vo.TransactionOrderVO;
import com.eastfair.projectcore.enumeration.MenuAffiliationEnum;
import com.eastfair.venuebooking.api.BondManageFeign;
import com.eastfair.venuebooking.api.HomeServiceOrderFeign;
import com.eastfair.venueservice.dto.BondManageDTO;
import com.eastfair.venueservice.dto.ServiceOrderDTO;
import com.eastfair.venueservice.enumeration.ServiceOrderPayStatusEnum;
import io.seata.common.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 交易订单
 * </p>
 *
 * @author fwl
 * @date 2023-02-13
 */
@Slf4j
@Service
public class TransactionOrderServiceImpl extends SuperServiceImpl<TransactionOrderMapper, TransactionOrder> implements TransactionOrderService {

    @Value("${chinaums.foodToken}")
    private String foodToken;
    @Value("${chinaums.foodUrl}")
    private String foodUrl;
    @Resource
    private CollectRecordService collectRecordService;

    @Resource
    private CollectionAccountService collectionAccountService;

    @Resource
    private PaymentPlanService paymentPlanService;

    @Resource
    private ChinaumsLogService chinaumsLogService;


    private static final String REFUND_NUM_FIELD = "pay_order_no";
    @Value("${mice-pay.transactionOrder.preno}")
    private String preno;

    private static final int REFUND_NUM_LENGTH = 7;

    @Resource
    private JyService jyService;

    @Resource
    private FinanceFeign financeService;

    @Resource
    private JyLogService jyLogService;

    @Resource
    private CertificateApiFeign certificateApiFeign;

    @Resource
    private HomeServiceOrderFeign homeServiceOrderFeign;

    @Resource
    private BondManageFeign bondManageFeign;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<TransactionOrder> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    /**
     * 基础数据
     *
     * @param model
     * @return
     */
    @Override
    protected R<Boolean> handlerSave(TransactionOrder model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTenantId(ContextUtil.getTenantId());
        //雪花ID
        return R.successDef();
    }

    /**
     * 通用查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    public List<TransactionOrder> list(TransactionOrderDTO modelDTO, List<Long> ids) {
        return ((TransactionOrderService) AopContext.currentProxy()).listOfCache(modelDTO, ids);
    }

    @Override
    public TransactionOrder getByOrderNum(String orderNum) {
        LambdaQueryWrapper<TransactionOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TransactionOrder::getIsDeleted, BusinessConstant.DELETE_NO);
        lambdaQueryWrapper.eq(TransactionOrder::getOrderNum, orderNum);
        return baseMapper.selectOne(lambdaQueryWrapper);
    }


    /**
     * 缓存查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    @Cache(key = "",
            magic = @Magic(
                    key = "{" +
                            "{'isEnabled', #args[0]?.isEnabled}," +
                            "{'exhibitionName', #args[0]?.exhibitionName}," +
                            "{'exhibitionId', #args[0]?.exhibitionId}," +
                            "{'orderType', #args[0]?.orderType}," +
                            "{'orderNum', #args[0]?.orderNum}," +
                            "{'orderAmount', #args[0]?.orderAmount}," +
                            "{'orderTime', #args[0]?.orderTime}," +
                            "{'payer', #args[0]?.payer}," +
                            "{'payType', #args[0]?.payType}," +
                            "{'mainno', #args[0]?.mainno}," +
                            "{'id', #args[1]}" +
                            "}"))
    public List<TransactionOrder> listOfCache(TransactionOrderDTO modelDTO, List<Long> ids) {
        //查询
        TransactionOrder queryModel = new TransactionOrder();
        if (modelDTO != null) {
            BeanUtils.copyProperties(modelDTO, queryModel);
        }
        QueryWrap<TransactionOrder> wrapper = Wraps.q(queryModel);
        if (ids != null && !ids.isEmpty()) {
            wrapper.lambda().in(TransactionOrder::getId, ids);
        }
        //添加其他业务查询条件
        wrapper.lambda().eq(TransactionOrder::getIsDeleted, BusinessConstant.DELETE_NO);
        List<TransactionOrder> modelList = list(wrapper);
        return modelList;
    }

    /**
     * @param transactionOrderDTO
     * @return void
     * @Author clm
     * @Description //保存更新
     * @Date 16:48 2023/2/13
     * @Param [transactionOrderDTO]
     */
    @Override
    public void saveOrUpdate(TransactionOrderDTO transactionOrderDTO) {

        TransactionOrder transactionOrder = new TransactionOrder();
        BeanUtils.copyProperties(transactionOrderDTO, transactionOrder);

        saveOrUpdate(transactionOrder);
    }

    /**
     * @param params
     * @return com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.eastfair.pay.vo.TransactionOrderVO>
     * @Author clm
     * @Description //交易记录分页查询
     * @Date 17:11 2023/2/13
     * @Param [params]
     */
    @Override
    public Page<TransactionOrderVO> queryList(PageParams<TransactionOrderPageQuery> params) {
        TransactionOrderPageQuery transactionOrderPageQuery = params.getModel();
        LambdaQueryWrapper<TransactionOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(transactionOrderPageQuery.getOrderType() != null, TransactionOrder::getOrderType, transactionOrderPageQuery.getOrderType());
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(transactionOrderPageQuery.getPayType()), TransactionOrder::getPayType, transactionOrderPageQuery.getPayType());
        lambdaQueryWrapper.eq(transactionOrderPageQuery.getOrderStatus() != null, TransactionOrder::getOrderStatus, transactionOrderPageQuery.getOrderStatus());
        lambdaQueryWrapper.like(StrUtil.isNotBlank(transactionOrderPageQuery.getSystemName()), TransactionOrder::getSystemName, transactionOrderPageQuery.getSystemName());
        lambdaQueryWrapper.like(StrUtil.isNotBlank(transactionOrderPageQuery.getExhibitionName()), TransactionOrder::getExhibitionName, transactionOrderPageQuery.getExhibitionName());
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(transactionOrderPageQuery.getOrderNum()), TransactionOrder::getOrderNum, transactionOrderPageQuery.getOrderNum());
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(transactionOrderPageQuery.getMainno()), TransactionOrder::getMainno, transactionOrderPageQuery.getMainno());
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(transactionOrderPageQuery.getPayOrderNo()), TransactionOrder::getPayOrderNo, transactionOrderPageQuery.getPayOrderNo());

        Page<TransactionOrder> buildPage = params.buildPage();
        Page<TransactionOrder> queryPage = page(buildPage, lambdaQueryWrapper);
        Page<TransactionOrderVO> transactionOrderVOPage = ConvertUtil.convertPage(queryPage, TransactionOrderVO.class);
        return transactionOrderVOPage;
    }

    /**
     * @param transactionOrderDTO
     * @return void
     * @Author fwl
     * @Description //保存
     * @Date 14:12 2023/2/17
     * @Param [transactionOrderDTO]
     */
    @Override
    public boolean save(TransactionOrderDTO transactionOrderDTO) {
        TransactionOrder order = getByOrderNum(transactionOrderDTO.getOrderNum());
        if (order != null) {
            log.info("交易订单已存在,order={}", order);
            throw new BizException(10, "交易订单已存在");
        }
        TransactionOrder transactionOrder = new TransactionOrder();
        BeanUtils.copyProperties(transactionOrderDTO, transactionOrder);
        List<OrderPaymentPlan> paymentPlans = transactionOrderDTO.getPaymentPlan();
        if (CollectionUtils.isNotEmpty(paymentPlans)) {
            transactionOrder.setPaymentPlan(JSON.toJSONString(paymentPlans));
        }
        transactionOrder.setSystemScene(ContextUtil.getSystemScene());
        //根据系统标识获取商户名称
        // 1.业务系统传来收款单位
        // 2.到收款账户里查询，查询到存在收款单位推送财务系统，不存在收款单位,提示业务系统“请到财务系统配置账号”
        // 3.把没有返回交易订单流水号的数据 定时任务1小时执行一次
        if (StringUtils.isEmpty(transactionOrderDTO.getPayee())) {
            log.error("交易订单收款单位不能为空,transactionOrderDTO={}", transactionOrderDTO);
            throw new BizException(PayExceptionCode.PAYEE_IS_EMPTY.getCode(), PayExceptionCode.PAYEE_IS_EMPTY.getMsg());
        }
        transactionOrder.setPayee(transactionOrderDTO.getPayee());
        if (StringUtils.isEmpty(transactionOrderDTO.getSystemCode())) {
            transactionOrder.setSystemCode(MenuAffiliationEnum.get(ContextUtil.getSystemScene()).getCode());
            transactionOrder.setSystemName(MenuAffiliationEnum.get(ContextUtil.getSystemScene()).getDesc());
        } else {
            transactionOrder.setSystemCode(MenuAffiliationEnum.get(transactionOrderDTO.getSystemCode()).getCode());
            transactionOrder.setSystemName(MenuAffiliationEnum.get(transactionOrderDTO.getSystemCode()).getDesc());
        }
        //生成订单号
//        String prefix = preno + DateUtil.format(new Date(), "yyyyMMddmmHHssSSS");
//        String refundNum = CreatCode.creatCode(baseMapper, REFUND_NUM_FIELD, REFUND_NUM_LENGTH, prefix);
//        transactionOrder.setPayOrderNo(refundNum);
        //保存订单信息
        transactionOrder.setState(OrderStateEnum.IN_PROGRESS.getCode());
        save(transactionOrder);
        log.info("保存交易订单成功，transactionOrder={}", transactionOrder);
        CollectionAccount collectionAccount = collectionAccountService.lambdaQuery().eq(CollectionAccount::getCompanyName, transactionOrderDTO.getPayee())
                .eq(CollectionAccount::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(CollectionAccount::getIsEnabled, BusinessConstant.YES).one();
        if (Objects.isNull(collectionAccount)) {
            throw new BizException(PayExceptionCode.FINANCIAL_ACCOUNT_DOES_NOT_EXIST.getCode(), PayExceptionCode.FINANCIAL_ACCOUNT_DOES_NOT_EXIST.getMsg());
        }
        //订单同步至荆艺
        JYReq<JYTransactionOrderDTO> jyReqestDTO = jyService.buildAddTransactionOrderToJy(transactionOrder);
        log.info("同步交易订单入参，req={}", jyReqestDTO);
        JyLog jyLog = new JyLog()
                .setMethodName("新增交易订单同步")
                .setTableName(transactionOrder.getClass().getName())
                .setLinkId(String.valueOf(transactionOrder.getId()))
                .setRequestParameter(JSON.toJSONString(jyReqestDTO));
        try {
            R<List<JYMainnoResultDTO>> result = financeService.sync(jyReqestDTO);
            jyLog.setResponseResults(JSON.toJSONString(result));
            log.info("同步交易订单出参，result={}", result);
            if (result != null && result.getIsSuccess()) {
                jyLog.setIsSuccess(BusinessConstant.ENABLE_YES);
                if (CollectionUtils.isNotEmpty(result.getData())) {
                    transactionOrder.setMainno(result.getData().get(0).getMainno());
                    updateById(transactionOrder);
                    log.info("更新交易订单流水号成功");
                }
            }
        } catch (Exception e) {
            log.error("订单同步荆艺失败");
        }
        jyLogService.save(jyLog);
        return true;
    }

    /**
     * @param transactionOrderDTO
     * @return void
     * @Author fwl
     * @Description //更新
     * @Date 14:12 2023/2/17
     * @Param [transactionOrderDTO]
     */
    @Override
    public void updateById(TransactionOrderDTO transactionOrderDTO) {
        TransactionOrder transactionOrder = getByOrderNum(transactionOrderDTO.getOrderNum());
        log.info("查询交易订单,transactionOrder={}", transactionOrder);
        if (transactionOrder == null) {
            throw new BizException("交易订单不存在，orderNum=" + transactionOrder.getOrderNum());
        }
        //查询订单认领记录
        CollectRecord collectRecord = collectRecordService.getRecordByOrderNum(transactionOrder.getOrderNum());
        log.info("查询认款记录,collectRecord={}", collectRecord);
        if (collectRecord != null) {
            throw new BizException("存在认款记录，不允许修改订单付款计划，orderNum=" + transactionOrder.getOrderNum());
        }
        if(CollectionUtils.isNotEmpty(transactionOrderDTO.getPaymentPlan())){
            transactionOrder.setPaymentPlan(JSON.toJSONString(transactionOrderDTO.getPaymentPlan()));
        }
        if (Objects.nonNull(transactionOrderDTO.getPaymentPeriods())){
            transactionOrder.setPaymentPeriods(transactionOrderDTO.getPaymentPeriods());
        }
        if (Objects.nonNull(transactionOrderDTO.getOrderAmount())){
            transactionOrder.setOrderAmount(transactionOrderDTO.getOrderAmount());
        }
        updateById(transactionOrder);
        log.info("更新付款计划成功，transactionOrder={}", transactionOrder);
        //订单同步至荆艺
        JYReq<JYTransactionOrderDTO> jyReqestDTO = jyService.buildUpdateTransactionOrderToJy(transactionOrder);
        log.info("同步交易订单入参，req={}", jyReqestDTO);
        JyLog jyLog = new JyLog()
                .setMethodName("更新交易订单同步")
                .setTableName(transactionOrder.getClass().getName())
                .setLinkId(String.valueOf(transactionOrder.getId()))
                .setRequestParameter(JSON.toJSONString(jyReqestDTO));
        try {
            R<List<JYMainnoResultDTO>> result = financeService.sync(jyReqestDTO);
            jyLog.setResponseResults(JSON.toJSONString(result));
            log.info("同步交易订单出参，result={}", result);
            if (result != null && result.getIsSuccess()) {
                jyLog.setIsSuccess(BusinessConstant.ENABLE_YES);
                if (CollectionUtils.isNotEmpty(result.getData())) {
                    transactionOrder.setMainno(result.getData().get(0).getMainno());
                    updateById(transactionOrder);
                    log.info("更新交易订单流水号成功");
                }
            }
        } catch (Exception e) {
            log.error("订单同步荆艺失败");
        }
        jyLogService.save(jyLog);
    }

    /**
     * @return void
     * @Author fwl
     * @Description //取消交易订单
     * @Date 14:12 2023/3/17
     * @Param [orderNum]
     **/
    @Override
    public void cancel(String orderNum) {
        TransactionOrder transactionOrder = getByOrderNum(orderNum);
        log.info("查询交易订单,transactionOrder={}", transactionOrder);
        if (transactionOrder == null) {
            throw new BizException("交易订单不存在，orderNum=" + orderNum);
        }
        //查询订单认领记录
        List<CollectRecord> collectRecord = collectRecordService.getRecordListByOrderNum(transactionOrder.getOrderNum());
        log.info("查询认款记录,collectRecord={}", collectRecord);
        if (CollectionUtils.isNotEmpty(collectRecord)) {
            throw new BizException("存在认款记录，不允许取消订单，orderNum=" + transactionOrder.getOrderNum());
        }
        transactionOrder.setState(OrderStateEnum.CANCELED.getCode());
        updateById(transactionOrder);
        log.info("取消交易订单成功，transactionOrder={}", transactionOrder);
        //同步荆艺
        if (StringUtils.isNotBlank(transactionOrder.getMainno())) {
            JYReq<JYTransactionOrderDTO> jyReqestDTO = jyService.buildCancelTransactionOrderToJy(transactionOrder);
            log.info("取消交易订单入参，req={}", jyReqestDTO);
            JyLog jyLog = new JyLog()
                    .setMethodName("取消交易订单同步")
                    .setTableName(transactionOrder.getClass().getName())
                    .setLinkId(String.valueOf(transactionOrder.getId()))
                    .setRequestParameter(JSON.toJSONString(jyReqestDTO));
            R<List<JYMainnoResultDTO>> result = null;
            try {
                result = financeService.sync(jyReqestDTO);
                jyLog.setResponseResults(JSON.toJSONString(result));
                jyLog.setIsSuccess(BusinessConstant.ENABLE_YES);
                log.info("取消交易订单出参，result={}", result);
            } catch (Exception e) {
                log.error("订单同步荆艺失败");
            }
            jyLogService.save(jyLog);
            return;
        }
        log.info("交易流水号不存在,orderNum={}", orderNum);
    }


    /**
     * do转vo
     *
     * @param model model
     * @return modelVo
     */
    @Override
    public TransactionOrderVO doToVo(TransactionOrder model) {
        TransactionOrderVO modelVo = new TransactionOrderVO();
        BeanUtils.copyProperties(model, modelVo);
        modelVo.setId(model.getId());
        return modelVo;
    }

    /**
     * do转vo
     *
     * @param modelList modelList
     * @return list
     */
    @Override
    public List<TransactionOrderVO> doToVos(List<TransactionOrder> modelList) {
        if (modelList == null || modelList.isEmpty()) {
            return null;
        }
        List<TransactionOrderVO> result = new ArrayList<>();
        for (TransactionOrder model : modelList) {
            result.add(doToVo(model));
        }
        return result;
    }

    @Override
    public List<TransactionOrder> queryTransactionOrderDetails(Long id, String orderType) {
        Map<String, String> map = new HashMap<>();
        map.put("PAYED", "PAYED");
        map.put("PART_PAY", "PARTPAY");
        map.put("UN_PAY", "UNPAY");
        map.put("IS_EXPIRES", "UNPAY");
        List<TransactionOrder> list = new ArrayList<>();
        TransactionOrder order = lambdaQuery().eq(TransactionOrder::getId, id).eq(TransactionOrder::getOrderType, orderType).one();
        if (TransactionOrderOrderTypeEnum.CONTRACT.eq(TransactionOrderOrderTypeEnum.valueOf(orderType))) {
            // 合同
            // 查询付款计划
            if (StrUtil.isBlank(order.getPaymentPlan())) {
                list.add(order);
            } else {
                List<OrderPaymentPlan> paymentPlans = JSON.parseArray(order.getPaymentPlan(), OrderPaymentPlan.class);
                if (CollectionUtils.isEmpty(paymentPlans)) {
                    // 付款计划为空
                    list.add(order);
                } else {

                    for (int i = 0; i < paymentPlans.size(); i++) {
                        TransactionOrder t = new TransactionOrder();
                        BeanUtils.copyProperties(order, t);
                        t.setOrderStatus(TransactionOrderOrderStatusEnum.valueOf(StrUtil.isBlank(paymentPlans.get(i).getPayState()) ? "UNPAY" : map.get(paymentPlans.get(i).getPayState())));
                        t.setPaymentPeriods(StrUtil.isBlank(paymentPlans.get(i).getStagesTag()) ? (i + 1) : Integer.parseInt(paymentPlans.get(i).getStagesTag()));
                        t.setOrderTime(LocalDateTime.parse(paymentPlans.get(i).getFkrq(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                        t.setOrderAmount(paymentPlans.get(i).getFkje());
                        t.setPayOrderNo(StrUtil.isBlank(paymentPlans.get(i).getPayOrderNo())?"":paymentPlans.get(i).getPayOrderNo());
                        list.add(t);

                    }
                }
            }
        } else {
            list.add(order);
        }
        return list;
    }

    @Override
    public Boolean onlinePayment(PaymentDTO dto, ChinaumsLogDTO chinaumsLog) {
        log.info("在线支付同步订单状态,dto={}", dto);
        TransactionOrder order = lambdaQuery()
                .eq(TransactionOrder::getOrderNum, dto.getOrderNum())
                .eq(Objects.nonNull(dto.getOrderType()), TransactionOrder::getOrderType, dto.getOrderType().getCode()).one();
        if (Objects.isNull(order)) {
            throw new BizException("交易订单不存在，orderNum={}" + dto.getOrderNum());
        }
        order.setPayOrderNo(dto.getTransactionSerialNum());
        order.setPaymentTime(dto.getPaymentTime());
        order.setOrderStatus(dto.getOrderStatus());
        order.setState(OrderStateEnum.COMPLETED.getCode());
        order.setPayType(dto.getPayType());
        order.setPayChannel(dto.getPayChannel());
        JyLog jyLog = new JyLog()
                .setMethodName("付款推送")
                .setTableName(order.getClass().getName())
                .setLinkId(String.valueOf(order.getId()));
        // 同步业务系统
        updateBizPayStatus(order,chinaumsLog);

        // 同步荆艺
        try {
            JYReq<JYPaymentDTO> jyReq = jyService.buildSuccessPaymentToJy(order, dto);
            log.info("付款推送荆艺入参，req={}", jyReq);
            jyLog.setRequestParameter(JSON.toJSONString(jyReq));
            R<List<JYMainnoResultDTO>> result = financeService.sync(jyReq);
            jyLog.setResponseResults(JSON.toJSONString(result));
            log.info("付款推送荆艺出参，result={}", result);
            if (result != null && result.getIsSuccess()) {
                jyLog.setIsSuccess(BusinessConstant.ENABLE_YES);
                log.error("付款推送荆艺成功");
            }
        } catch (Exception e) {
            log.error("付款推送荆艺失败");
        }
        updateById(order);
        log.error("更新订单状态成功");
        jyLogService.save(jyLog);
        return true;
    }

    /**
     * 同步业务系统
     *
     * @param order order
     * @param chinaumsLog
     */
    private void updateBizPayStatus(TransactionOrder order, ChinaumsLogDTO chinaumsLog) {
        TransactionOrderOrderStatusEnum orderStatus = order.getOrderStatus();
        TransactionOrderOrderTypeEnum orderType = order.getOrderType();
        String orderNum = order.getOrderNum();
        if (orderType.eq(TransactionOrderOrderTypeEnum.SERVICE)) {
            // 服务
            ServiceOrderDTO serviceOrderDTO = new ServiceOrderDTO();
            serviceOrderDTO.setOrderNumber(orderNum);
            serviceOrderDTO.setActualPayAmount(order.getOrderAmount());
            serviceOrderDTO.setPayWay(order.getPayType());
            serviceOrderDTO.setPayer(order.getPayer());
            homeServiceOrderFeign.payServiceOrder(serviceOrderDTO);
        } else if (orderType.eq(TransactionOrderOrderTypeEnum.CERTIFICATE)) {
            // 证件
            CertificateOrderDTO certificateOrderDTO = new CertificateOrderDTO();
            certificateOrderDTO.setOrderNumber(orderNum);
            certificateOrderDTO.setOrderMoney(order.getOrderAmount());
            certificateApiFeign.payOrder(certificateOrderDTO);
        }else if (orderType.eq(TransactionOrderOrderTypeEnum.BOND)) {
            // 保证金
            BondManageDTO bondManageDTO = new BondManageDTO();
            bondManageDTO.setOrderNumber(orderNum);
            bondManageDTO.setPayAmount(order.getOrderAmount());
            bondManageDTO.setPayType(order.getPayType());
            bondManageFeign.payBond(bondManageDTO);
        }else if (orderType.eq(TransactionOrderOrderTypeEnum.FOOD)) {
            log.info("回写餐饮订单，{}，{}",foodUrl,chinaumsLog);
            String response = request(foodUrl, JSONObject.toJSONString(chinaumsLog),foodToken);
            log.info("回写餐饮订单返回 {}",response);
        }
    }


    /**
     * 发送http请求
     * @param url 请求url
     * @param reqBody  请求体
     * @return response
     */
    static String request(String url, String reqBody,String foodToken){
        String response = "";
        PrintWriter out = null;
        BufferedReader in = null;
        try{
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
            httpUrlConnection.setRequestProperty("Content-Type", "application/json");
            httpUrlConnection.setRequestProperty("token", foodToken);
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            log.info("token:{}",foodToken);
            out = new PrintWriter(httpUrlConnection.getOutputStream());
            out.write(reqBody);
            out.flush();
            httpUrlConnection.connect();
            in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                response += line;
            }
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            try {
                if (out != null) { out.close();}
                if (in != null) {in.close();}
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return response;
    }

    private ServiceOrderPayStatusEnum matchServiceOrderStatus(TransactionOrderOrderStatusEnum orderStatus) {
        if (Objects.nonNull(orderStatus)) {
            if (orderStatus.eq(TransactionOrderOrderStatusEnum.PAYED)) {
                return ServiceOrderPayStatusEnum.HAS_PAY;
            }
        }
        return null;
    }

    @Override
    public void executeSyncOrderToJY(List<String> orderNumList) {
        log.info("================= 开始执行 同步订单到荆艺的定时任务 =================");
        List<TransactionOrder> list;
        if (CollectionUtils.isEmpty(orderNumList)) {
            list = lambdaQuery()
                    .eq(TransactionOrder::getIsDeleted, BusinessConstant.DELETE_NO)
                    .eq(TransactionOrder::getIsEnabled, BusinessConstant.YES)
                    .and((wrapper) -> wrapper.isNull(TransactionOrder::getMainno).or().eq(TransactionOrder::getMainno, ""))
                    .list();
        } else {
            list = lambdaQuery()
                    .eq(TransactionOrder::getIsDeleted, BusinessConstant.DELETE_NO)
                    .eq(TransactionOrder::getIsEnabled, BusinessConstant.YES)
                    .in(TransactionOrder::getOrderNum, orderNumList)
                    .and((wrapper) -> wrapper.isNull(TransactionOrder::getMainno).or().eq(TransactionOrder::getMainno, ""))
                    .list();
        }
        log.info("未同步到荆艺的订单,TransactionOrderList={}", list);
        if (CollectionUtils.isEmpty(list)) {
            log.info("================= 执行完毕 同步订单到荆艺的定时任务 =================");
            return;
        }
        list.forEach(l -> {
            JYReq<JYTransactionOrderDTO> jyReqestDTO = jyService.buildAddTransactionOrderToJy(l);
            try {
                R<List<JYMainnoResultDTO>> result = financeService.sync(jyReqestDTO);
                log.info("定时任务同步交易订单出参，result={}", result);
                if (result != null && result.getIsSuccess()) {
                    if (CollectionUtils.isNotEmpty(result.getData())) {
                        l.setMainno(result.getData().get(0).getMainno());
                        updateById(l);
                        log.info("定时任务更新交易订单流水号成功");
                    }
                }
            } catch (Exception e) {
                log.error("定时任务订单同步荆艺失败");
            }
        });
        log.info("================= 执行完毕 同步订单到荆艺的定时任务 =================");
    }

    @Override
    public TransactionOrderVO queryOrderDetailsByOrderNum(String orderNum) {
        TransactionOrder order = lambdaQuery().eq(TransactionOrder::getOrderNum, orderNum)
                .eq(TransactionOrder::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(TransactionOrder::getIsEnabled, BusinessConstant.ENABLE_YES).one();
        if (Objects.isNull(order)) {
            return null;
        }
        return doToVo(order);
    }

    @Override
    public void updateOrderStatus(TransactionOrderDTO transactionOrderDTO) {
        TransactionOrder order = lambdaQuery().eq(TransactionOrder::getOrderNum, transactionOrderDTO.getOrderNum())
                .eq(TransactionOrder::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(TransactionOrder::getIsEnabled, BusinessConstant.ENABLE_YES).one();
        if (Objects.isNull(order)) {
            throw new BizException("交易订单不存在，orderNum={}" + transactionOrderDTO.getOrderNum());
        }
        order.setOrderStatus(transactionOrderDTO.getOrderStatus());
        updateById(order);
        log.info("更新订单交易状态成功！");
    }

    @Override
    public void checkPayStatus(Long id) {
        TransactionOrder order = lambdaQuery().eq(TransactionOrder::getId, id).one();
        log.info("查询到的TransactionOrder {}", order);
        if (Objects.isNull(order)) {
            throw BizException.wrap(PayExceptionCode.TRANSACTION_ORDER_NOT_EXIST);
        }
//        if (!PayTypeEnum.ONLINE_PAY.getCode().equals(order.getPayType())){
//            return;
//        }
        ChinaumsLogDTO chinaumsLogDTO = new ChinaumsLogDTO();
        chinaumsLogDTO.setOrderNum(order.getOrderNum());
        chinaumsLogDTO.setOrderType(order.getOrderType());
        chinaumsLogService.queryPayStatus(chinaumsLogDTO);
    }

    @Override
    public boolean batchSave(List<TransactionOrderDTO> transactionOrderList) {
        Integer count = lambdaQuery().in(TransactionOrder::getOrderNum, transactionOrderList.stream().map(TransactionOrderDTO::getOrderNum).collect(Collectors.toList())).count();
        if (count > 0) {
            // 有订单已存在
            log.info("交易订单已存在");
            throw new BizException(10, "交易订单已存在");
        }

        boolean flag = transactionOrderList.stream().anyMatch(order -> StrUtil.isBlank(order.getPayee()));
        if (flag) {
            log.error("交易订单收款单位不能为空,transactionOrderList={}", transactionOrderList);
            throw new BizException(PayExceptionCode.PAYEE_IS_EMPTY.getCode(), PayExceptionCode.PAYEE_IS_EMPTY.getMsg());
        }

        List<TransactionOrder> orders = transactionOrderList.stream().map(transactionOrderDTO -> {
            TransactionOrder transactionOrder = new TransactionOrder();
            BeanUtils.copyProperties(transactionOrderDTO, transactionOrder);
            List<OrderPaymentPlan> paymentPlans = transactionOrderDTO.getPaymentPlan();
            if (CollectionUtils.isNotEmpty(paymentPlans)) {
                transactionOrder.setPaymentPlan(JSON.toJSONString(paymentPlans));
            }
            transactionOrder.setSystemScene(ContextUtil.getSystemScene());
            //根据系统标识获取商户名称
            // 1.业务系统传来收款单位
            // 2.到收款账户里查询，查询到存在收款单位推送财务系统，不存在收款单位,提示业务系统“请到财务系统配置账号”
            // 3.把没有返回交易订单流水号的数据 定时任务1小时执行一次
            if (StringUtils.isEmpty(transactionOrderDTO.getSystemCode())) {
                transactionOrder.setSystemCode(MenuAffiliationEnum.get(ContextUtil.getSystemScene()).getCode());
                transactionOrder.setSystemName(MenuAffiliationEnum.get(ContextUtil.getSystemScene()).getDesc());
            } else {
                transactionOrder.setSystemCode(MenuAffiliationEnum.get(transactionOrderDTO.getSystemCode()).getCode());
                transactionOrder.setSystemName(MenuAffiliationEnum.get(transactionOrderDTO.getSystemCode()).getDesc());
            }
            return transactionOrder;
        }).collect(Collectors.toList());
        saveBatch(orders);
        Set<String> payeeSet = orders.stream().map(TransactionOrder::getPayee).collect(Collectors.toSet());
        Integer collectCount = collectionAccountService.lambdaQuery().in(CollectionAccount::getCompanyName, payeeSet).count();
        if (payeeSet.size() != collectCount) {
            throw new BizException(PayExceptionCode.FINANCIAL_ACCOUNT_DOES_NOT_EXIST.getCode(), PayExceptionCode.FINANCIAL_ACCOUNT_DOES_NOT_EXIST.getMsg());
        }
        orders.forEach(transactionOrder -> {
            JYReq<JYTransactionOrderDTO> jyReqestDTO = jyService.buildAddTransactionOrderToJy(transactionOrder);
            log.info("同步交易订单入参，req={}", jyReqestDTO);
            JyLog jyLog = new JyLog()
                    .setMethodName("新增交易订单同步")
                    .setTableName(transactionOrder.getClass().getName())
                    .setLinkId(String.valueOf(transactionOrder.getId()))
                    .setRequestParameter(JSON.toJSONString(jyReqestDTO));
            try {
                R<List<JYMainnoResultDTO>> result = financeService.sync(jyReqestDTO);
                jyLog.setResponseResults(JSON.toJSONString(result));
                log.info("同步交易订单出参，result={}", result);
                if (result != null && result.getIsSuccess()) {
                    jyLog.setIsSuccess(BusinessConstant.ENABLE_YES);
                    if (CollectionUtils.isNotEmpty(result.getData())) {
                        transactionOrder.setMainno(result.getData().get(0).getMainno());
                        updateById(transactionOrder);
                        log.info("更新交易订单流水号成功");
                    }
                }
            } catch (Exception e) {
                log.error("订单同步荆艺失败");
            }
            jyLogService.save(jyLog);
        });

        return true;

    }
}
